package com.chenju.invokechainservice.domain;

import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.data.neo4j.core.schema.*;

import java.util.ArrayList;
import java.util.List;

@Node
@Data
@EqualsAndHashCode(callSuper = true)
public class TMethodNode extends BaseNode {
    private boolean isOverride;

    private boolean isAdvices;

    private boolean isPointcut;

    private boolean isInterface;

    private String mappingPath;

    private String returnType;

    private String descriptor;

    private String requestMethod;

    private List<String> thrownExceptions;

    @Relationship(type = "PARAMETER", direction = Relationship.Direction.INCOMING)
    private List<TParameterNode> parameters;

    @Relationship(type = "INVOKE", direction = Relationship.Direction.INCOMING)
    private List<TMethodNode> invokeMethods;

    @Relationship(type = "INTERFACE" , direction = Relationship.Direction.OUTGOING)
    private TInterfaceNode tInterfaceNode;

    @Relationship(type = "ADVICE", direction = Relationship.Direction.OUTGOING)
    private TMethodNode adviceForMethod;

    @Relationship(type = "EXTENDS", direction = Relationship.Direction.OUTGOING)
    private TMethodNode extendsMethodNode;

    @Relationship(type = "IMPLEMENTS", direction = Relationship.Direction.OUTGOING)
    private List<TMethodNode> implementsMethodNodes;

    @Relationship(type = "FEIGN", direction = Relationship.Direction.INCOMING)
    private TInterfaceNode feignInterface;

    @Relationship(type = "ANNOTATED", direction = Relationship.Direction.INCOMING)
    private List<TAnnotationNode> annotations;

    @Relationship(type = "LAMBDA", direction = Relationship.Direction.OUTGOING)
    private TMethodNode lambdaFromMethodNode;

    public TMethodNode() {
        super();
        this.invokeMethods = new ArrayList<>();
        this.thrownExceptions = new ArrayList<>();
        this.annotations = new ArrayList<>();
        this.implementsMethodNodes = new ArrayList<>();
    }

    public TMethodNode(String name) {
        super(name);
        this.invokeMethods = new ArrayList<>();
        this.thrownExceptions = new ArrayList<>();
        this.annotations = new ArrayList<>();
        this.implementsMethodNodes = new ArrayList<>();
    }

    public TMethodNode(String name, String descriptor) {
        super(name);
        this.descriptor = descriptor;
        this.invokeMethods = new ArrayList<>();
        this.thrownExceptions = new ArrayList<>();
        this.annotations = new ArrayList<>();
        this.implementsMethodNodes = new ArrayList<>();
    }

    public TMethodNode(String name, int beginLine, int endLine) {
        super(name, beginLine, endLine);
        this.isOverride = false;
        this.isAdvices = false;
        this.isPointcut = false;
        this.isInterface = false;
        this.implementsMethodNodes = new ArrayList<>();
        this.invokeMethods = new ArrayList<>();
        this.thrownExceptions = new ArrayList<>();
        this.annotations = new ArrayList<>();
    }

    @Override
    public int hashCode() {
        int result = super.hashCode();
        return result;
    }

    public void updateImplementsMethodNodes(TMethodNode node){
        this.implementsMethodNodes.add(node);
    }
}
